#pragma once

#include <DrawFunc.h>
#include <xmemdc.h>
#include <xdll.idl>
class IXpng;

class CXPngButton : public CWindowImpl<CXPngButton>
{
public:
	CXPngButton(void) :m_pPng(NULL), m_nButtonTypeCount(0), m_nButtonState(BUTTON_NORMAL), 
		m_bMouseLeave(FALSE), m_bButtonDown(FALSE)
	{
		//	m_tooltip.Create(this, NULL);
		m_rcClient.SetRectEmpty();
	}

	~CXPngButton(void)
	{
		if (m_pPng)
		{
			DeletePngObject(m_pPng);
		}
		m_pPng = NULL;

	}

	BEGIN_MSG_MAP_EX(CXPngButton)
		MESSAGE_RANGE_HANDLER(WM_MOUSEFIRST, WM_MOUSELAST, OnMouseMessage)
 		MSG_WM_LBUTTONDOWN(OnLButtonDown)
 		MSG_WM_LBUTTONUP(OnLButtonUp)
		MSG_WM_PAINT(OnPaint)
		MSG_WM_ERASEBKGND(OnEraseBkgnd)
		MSG_WM_MOUSEMOVE(OnMouseMove)
		MSG_WM_MOUSELEAVE(OnMouseLeave)
		MSG_WM_MOUSEHOVER(OnMouseHover)
	END_MSG_MAP()


	BOOL SubclassWindow(HWND hWnd)
	{
		HWND a = m_hWnd;
		BOOL bRet = CWindowImpl::SubclassWindow(hWnd);
		if(bRet)
			Init();
		return bRet;
	}

	void Init()
	{
		//	ModifyStyle(0, BS_OWNERDRAW);
		// create a tool tip
		m_tooltip.Create(m_hWnd);
		//	m_tooltip.ModifyStyle(0, TTS_ALWAYSTIP);
		ATLASSERT(m_tooltip.IsWindow());
		if(m_tooltip.IsWindow() && !m_strToolTip.IsEmpty())
		{
			m_tooltip.Activate(TRUE);	
			m_tooltip.AddTool(m_hWnd, (LPTSTR)(LPCTSTR)m_strToolTip);
		}
	}
	/*********   command ****************/
	LRESULT OnEraseBkgnd(HDC)
	{
		return FALSE;
	}
	LRESULT OnPaint(HDC hdc)
	{
		CPaintDC dc(m_hWnd);
		CRect rect;
		GetClientRect(&rect);

		CXMemDC memDC(dc.m_hDC, rect);

		CWindow parentWnd = GetParent();
		CRect parentRect(rect);
		ClientToScreen(parentRect);
		parentWnd.ScreenToClient(&parentRect);

		HDC parentDC = ::GetDC(parentWnd.m_hWnd);	
		::BitBlt(memDC.m_hDC, 0, 0,  parentRect.Width(), parentRect.Height(), parentDC, parentRect.left, parentRect.top, SRCCOPY);
		ReleaseDC(parentDC);

		if (m_pPng)
		{
			SIZE sz = m_pPng->GetPngSize();
			if (m_nButtonTypeCount)
			{
				int cx = sz.cx/m_nButtonTypeCount;
				m_pPng->DrawPngEx(memDC.m_hDC, rect, 0, 0, cx*m_nButtonState, sz.cx/m_nButtonTypeCount , 0, sz.cy);
			}
			else
			{
				m_pPng->DrawPngEx(memDC.m_hDC, rect, 0, 0, 0, sz.cx , 0, sz.cy);
			}
		}

		if (!m_strText.IsEmpty())
		{
			DrawMyText(memDC.m_hDC, m_strText, rect, RGB(0, 0, 0), DT_CENTER | DT_SINGLELINE | DT_VCENTER);
		}

		return 0;
	}
	LRESULT OnMouseHover(WPARAM wParam, CPoint pt)
	{
		// 	if (m_tooltip.m_hWnd)
		// 	{
		// 		m_tooltip.UpdateTipText((LPTSTR)(LPCTSTR)m_strToolTip, m_hWnd, GetDlgCtrlID());
		// 
		// 		m_tooltip.Activate(TRUE);
		// 	}
		return 0;
	}
	LRESULT OnMouseMove(WPARAM wParam, CPoint pt)
	{
		if (!m_bMouseLeave)
		{
			TRACKMOUSEEVENT mouseevent = {0};
			mouseevent.cbSize = sizeof(TRACKMOUSEEVENT);
			mouseevent.dwFlags = TME_LEAVE;
			mouseevent.hwndTrack = m_hWnd;
			::TrackMouseEvent(&mouseevent);


			// 		TRACKMOUSEEVENT mouseevent1 = {0};
			// 		mouseevent1.cbSize = sizeof(TRACKMOUSEEVENT);
			// 		mouseevent1.dwFlags = TME_HOVER;
			// 		mouseevent1.hwndTrack = m_hWnd;
			// 		::TrackMouseEvent(&mouseevent1);


			m_bMouseLeave = TRUE;
		}
		if (m_bButtonDown)
		{
			return 0;
		}
		if (m_nButtonState != BUTTON_HOVER)
		{
			m_nButtonState = BUTTON_HOVER;
			Invalidate(FALSE);
		}

		return 0;
	}

	LRESULT OnMouseLeave()
	{
		m_bMouseLeave = FALSE;
		m_bButtonDown = FALSE;
		if (m_nButtonState != BUTTON_NORMAL)
		{
			m_nButtonState = BUTTON_NORMAL;
			Invalidate(FALSE);
		}
		// 	if (m_tooltip.m_hWnd)
		// 	{
		// 		m_tooltip.Activate(FALSE);
		// 	}
		CPoint pt;
		GetCursorPos(&pt);
		HWND hParent = GetParent();
		::PostMessage(hParent, WM_MOUSEMOVE, NULL, MAKELPARAM(pt.x, pt.y));
		return 0;
	}

	LRESULT OnLButtonDown(WPARAM wParam, CPoint pt)
	{
		m_bButtonDown = TRUE;
		if (m_nButtonState != BUTTON_PUSHED)
		{
			m_nButtonState = BUTTON_PUSHED;
			Invalidate(FALSE);
		}
		return 0;
	}

	LRESULT OnLButtonUp(WPARAM wParam, CPoint pt)
	{
		if (m_bButtonDown)
		{
			int nID = GetDlgCtrlID();
			::PostMessage(GetParent(), WM_COMMAND, nID, 0);	
		}
		m_bButtonDown = FALSE;
		if (m_nButtonState != BUTTON_HOVER)
		{
			m_nButtonState = BUTTON_HOVER;
			Invalidate(FALSE);
		}
		return 0;
	}
	LRESULT OnMouseMessage(UINT uMsg, WPARAM wParam, LPARAM lParam, BOOL& bHandled)
	{
		MSG msg = { m_hWnd, uMsg, wParam, lParam };
		if(m_tooltip.IsWindow())
			m_tooltip.RelayEvent(&msg);
		bHandled = FALSE;
		return 1;

	}
	/*********   function ****************/
	void SetButtonPng(const CString & str, int nStateCount)
	{
		if (nStateCount <= 0 || !::PathFileExists(str))
		{
			return;
		}

		if (m_pPng != NULL)
		{
			DeletePngObject(m_pPng);
			m_pPng = NULL;
		}
		m_pPng = NewPngObject();
		if (m_pPng)
		{
			m_pPng->LoadPngFile(str);
			SIZE sz = m_pPng->GetPngSize();
			CRect rect;
			GetClientRect(&rect);
			rect.right = rect.left + sz.cx / nStateCount;
			rect.bottom = rect.top + sz.cy;
			SetWindowPos(NULL, rect, SWP_SHOWWINDOW | SWP_NOMOVE);
			GetClientRect(&rect);
			m_rcClient = rect;
		}
		m_nButtonTypeCount = nStateCount;
	}

	void SetTooltip(const CString & str)
	{
		m_strToolTip = str;
		if(m_strToolTip.IsEmpty())
		{
			if(m_tooltip.IsWindow())
				m_tooltip.Activate(FALSE);
			return;
		}

		if(m_tooltip.IsWindow())
		{
			m_tooltip.Activate(TRUE);	
			m_tooltip.AddTool(m_hWnd, (LPTSTR)(LPCTSTR)m_strToolTip);

		}
	}


	CRect GetRect()
	{
		CRect rect(m_rcClient);
		ClientToScreen(&rect);
		return rect;
	}

	void SetText(const CString & str){m_strText = str;};

private:
	IXpng *			m_pPng;
	CString			m_strPngPath;
	int				m_nButtonTypeCount;
	int				m_nButtonState;
	CString			m_strText;

	CRect			m_rcClient;

	BOOL			m_bMouseLeave;
	BOOL			m_bButtonDown;

	CToolTipCtrl	m_tooltip;
	CString			m_strToolTip;
};
